#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
密码管理相关路由
"""
import csv
import io
from datetime import datetime
from fastapi import APIRouter, Request, Form, File, UploadFile, HTTPException
from fastapi.responses import HTMLResponse, Response
from fastapi.templating import Jinja2Templates
from starlette.responses import RedirectResponse

from ..database import get_db_connection, row_to_dict, rows_to_dict_list
from ..utils.config import config
from ..utils.security import generate_password, check_password_strength
from ..auth.session import get_current_user, verify_user

router = APIRouter()
templates = Jinja2Templates(directory="templates")


@router.get("/password-generator", response_class=HTMLResponse)
async def password_generator_page(request: Request):
    """密码生成器页面"""
    user = get_current_user(request)
    return templates.TemplateResponse("password_generator.html", {
        "request": request,
        "app_name": config.get('DEFAULT', 'app_name'),
        "company_name": config.get('DEFAULT', 'company_short'),
        "user": user
    })


@router.post("/api/generate-password")
async def api_generate_password(
    length: int = Form(12),
    use_numbers: bool = Form(True),
    use_letters: bool = Form(True),
    use_symbols: bool = Form(False)
):
    """密码生成API"""
    try:
        password = generate_password(length, use_numbers, use_letters, use_symbols)
        return {"password": password}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/api/check-password-strength")
async def api_check_password_strength(
    password: str = Form(...)
):
    """检查密码强度API"""
    try:
        strength = check_password_strength(password)
        return {"strength": strength}
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/passwords", response_class=HTMLResponse)
async def user_passwords(request: Request):
    """密码管理页面"""
    user = get_current_user(request)
    if not user:
        return RedirectResponse(url="/login", status_code=302)
    
    return templates.TemplateResponse("admin/passwords.html", {
        "request": request,
        "app_name": config.get('DEFAULT', 'app_name'),
        "company_name": config.get('DEFAULT', 'company_short'),
        "user": user,
        "is_admin": user['role'] == 'admin'
    })


@router.get("/api/passwords")
async def get_passwords(request: Request):
    """获取密码列表API"""
    user = get_current_user(request)
    if not user:
        raise HTTPException(status_code=401, detail="请先登录")
    
    conn = get_db_connection()
    
    if user['role'] == 'admin':
        # 管理员可以查看所有密码
        passwords = conn.execute("""
            SELECT p.id, p.url, p.account, p.description, p.created_at, p.updated_at,
                   u.username as user_name, p.user_id
            FROM passwords p
            JOIN users u ON p.user_id = u.id
            ORDER BY p.created_at DESC
        """).fetchall()
    else:
        # 普通用户只能查看自己的密码
        passwords = conn.execute("""
            SELECT p.id, p.url, p.account, p.description, p.created_at, p.updated_at,
                   u.username as user_name, p.user_id
            FROM passwords p
            JOIN users u ON p.user_id = u.id
            WHERE p.user_id = ?
            ORDER BY p.created_at DESC
        """, (user['id'],)).fetchall()
    
    conn.close()
    
    return {"passwords": rows_to_dict_list(passwords)}


@router.post("/api/passwords")
async def create_password(
    request: Request,
    url: str = Form(...),
    account: str = Form(...),
    password: str = Form(...),
    description: str = Form("")
):
    """创建密码API"""
    # 获取当前登录用户
    current_user = get_current_user(request)
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录")
    
    conn = get_db_connection()
    
    # 创建密码记录
    cursor = conn.cursor()
    cursor.execute("""
        INSERT INTO passwords (user_id, url, account, password, description)
        VALUES (?, ?, ?, ?, ?)
    """, (current_user['id'], url, account, password, description))
    
    password_id = cursor.lastrowid
    conn.commit()
    conn.close()
    
    
    
    return {"message": "密码创建成功", "password_id": password_id}


@router.put("/api/passwords/{password_id}")
async def update_password(
    request: Request,
    password_id: int,
    url: str = Form(...),
    account: str = Form(...),
    password: str = Form(...),
    description: str = Form("")
):
    """更新密码API"""
    # 获取当前登录用户
    current_user = get_current_user(request)
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录")
    
    conn = get_db_connection()
    cursor = conn.cursor()
    
    # 检查密码记录是否存在以及所属用户
    password_record = conn.execute("SELECT id, user_id, password FROM passwords WHERE id = ?", (password_id,)).fetchone()
    if not password_record:
        conn.close()
        raise HTTPException(status_code=404, detail="密码记录不存在")
    
    # 检查权限（管理员可以更新任何密码，普通用户只能更新自己的密码）
    if current_user['role'] != 'admin' and password_record['user_id'] != current_user['id']:
        conn.close()
        raise HTTPException(status_code=403, detail="无权更新此密码")
    
    # 获取旧密码
    old_password = password_record['password']
    
    # 记录密码历史
    cursor.execute("""
        INSERT INTO password_history (password_id, old_password, changed_by)
        VALUES (?, ?, ?)
    """, (password_id, old_password, current_user['id']))
    
    # 更新密码
    cursor.execute("""
        UPDATE passwords
        SET url = ?, account = ?, password = ?, description = ?, updated_at = ?
        WHERE id = ?
    """, (url, account, password, description, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), password_id))
    
    conn.commit()
    conn.close()
    
    
    
    return {"message": "密码更新成功"}


@router.delete("/api/passwords/{password_id}")
async def delete_password(request: Request, password_id: int):
    """删除密码API"""
    # 获取当前登录用户
    current_user = get_current_user(request)
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录")
    
    conn = get_db_connection()
    
    # 检查密码记录是否存在以及所属用户
    password_record = conn.execute("SELECT id, user_id, url FROM passwords WHERE id = ?", (password_id,)).fetchone()
    if not password_record:
        conn.close()
        raise HTTPException(status_code=404, detail="密码记录不存在")
    
    # 检查权限（管理员可以删除任何密码，普通用户只能删除自己的密码）
    if current_user['role'] != 'admin' and password_record['user_id'] != current_user['id']:
        conn.close()
        raise HTTPException(status_code=403, detail="无权删除此密码")
    
    # 获取密码信息用于日志记录
    url_info = password_record['url'] if password_record else f"ID:{password_id}"
    
    # 删除密码记录
    cursor = conn.cursor()
    cursor.execute("DELETE FROM passwords WHERE id = ?", (password_id,))
    conn.commit()
    conn.close()
    
    
    
    return {"message": "密码删除成功"}


@router.get("/api/passwords/{password_id}/detail")
async def get_password_detail(request: Request, password_id: int):
    """获取密码详情API"""
    current_user = get_current_user(request)
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录")
    
    conn = get_db_connection()
    
    # 查询密码详情
    password_record = conn.execute("""
        SELECT p.*, u.username as user_name
        FROM passwords p
        JOIN users u ON p.user_id = u.id
        WHERE p.id = ?
    """, (password_id,)).fetchone()
    
    if not password_record:
        conn.close()
        raise HTTPException(status_code=404, detail="密码记录不存在")
    
    # 检查权限
    if current_user['role'] != 'admin' and password_record['user_id'] != current_user['id']:
        conn.close()
        raise HTTPException(status_code=403, detail="无权查看此密码")
    
    conn.close()
    
    
    
    return {"password": row_to_dict(password_record)}


@router.get("/api/passwords/{password_id}/history")
async def get_password_history(request: Request, password_id: int):
    """获取密码历史API"""
    current_user = get_current_user(request)
    if not current_user:
        raise HTTPException(status_code=401, detail="请先登录")
    
    conn = get_db_connection()
    
    # 检查密码记录权限
    password_record = conn.execute("SELECT user_id FROM passwords WHERE id = ?", (password_id,)).fetchone()
    if not password_record:
        conn.close()
        raise HTTPException(status_code=404, detail="密码记录不存在")
    
    if current_user['role'] != 'admin' and password_record['user_id'] != current_user['id']:
        conn.close()
        raise HTTPException(status_code=403, detail="无权查看此密码历史")
    
    # 查询密码历史
    history = conn.execute("""
        SELECT ph.*, u.username as changed_by_name
        FROM password_history ph
        JOIN users u ON ph.changed_by = u.id
        WHERE ph.password_id = ?
        ORDER BY ph.changed_at DESC
    """, (password_id,)).fetchall()
    
    conn.close()
    
    return {"history": rows_to_dict_list(history)}


@router.post("/api/import/passwords")
async def import_passwords(
    request: Request,
    file: UploadFile = File(...),
    skip_duplicates: bool = Form(False)
):
    """导入密码API"""
    current_user = verify_user(request)
    
    if not file.filename.endswith(('.csv', '.xlsx', '.xls')):
        raise HTTPException(status_code=400, detail="只支持CSV、Excel文件格式")
    
    try:
        content = await file.read()
        
        # 解析文件内容
        if file.filename.endswith('.csv'):
            # CSV文件处理
            content_str = content.decode('utf-8-sig')  # 处理BOM
            csv_reader = csv.DictReader(io.StringIO(content_str))
            data_rows = list(csv_reader)
        else:
            # Excel文件处理
            import pandas as pd
            df = pd.read_excel(io.BytesIO(content))
            data_rows = df.to_dict('records')
        
        if not data_rows:
            raise HTTPException(status_code=400, detail="文件为空或格式错误")
        
        # 验证必需的列
        required_columns = ['URL', '账号', '密码']
        first_row = data_rows[0]
        missing_columns = [col for col in required_columns if col not in first_row]
        if missing_columns:
            raise HTTPException(status_code=400, detail=f"缺少必需的列: {', '.join(missing_columns)}")
        
        conn = get_db_connection()
        cursor = conn.cursor()
        
        success_count = 0
        skipped_count = 0
        error_count = 0
        errors = []
        
        for row_index, row in enumerate(data_rows, start=2):  # 从第2行开始（第1行是标题）
            try:
                url = str(row.get('URL', '')).strip()
                account = str(row.get('账号', '')).strip()
                password = str(row.get('密码', '')).strip()
                description = str(row.get('描述', '')).strip()
                
                if not url or not account or not password:
                    errors.append({
                        "row": row_index,
                        "message": "URL、账号和密码不能为空"
                    })
                    error_count += 1
                    continue
                
                # 检查是否已存在相同的密码记录
                existing_password = conn.execute(
                    "SELECT id FROM passwords WHERE user_id = ? AND url = ? AND account = ?", 
                    (current_user['id'], url, account)
                ).fetchone()
                
                if existing_password:
                    if skip_duplicates:
                        skipped_count += 1
                        continue
                    else:
                        errors.append({
                            "row": row_index,
                            "message": f"URL '{url}' 和账号 '{account}' 的组合已存在"
                        })
                        error_count += 1
                        continue
                
                # 创建密码记录
                cursor.execute("""
                    INSERT INTO passwords (user_id, url, account, password, description)
                    VALUES (?, ?, ?, ?, ?)
                """, (current_user['id'], url, account, password, description))
                
                success_count += 1
                
            except Exception as e:
                errors.append({
                    "row": row_index,
                    "message": f"处理失败: {str(e)}"
                })
                error_count += 1
        
        conn.commit()
        conn.close()
        
        # 
        
        return {
            "message": "密码导入完成",
            "total_count": len(data_rows),
            "success_count": success_count,
            "skipped_count": skipped_count,
            "error_count": error_count,
            "errors": errors[:10]  # 最多返回10个错误
        }
        
    except UnicodeDecodeError:
        raise HTTPException(status_code=400, detail="文件编码错误，请使用UTF-8编码")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导入失败: {str(e)}")


@router.get("/api/user/export/passwords")
async def export_user_passwords(request: Request):
    """导出用户密码API"""
    current_user = verify_user(request)
    
    conn = get_db_connection()
    passwords = conn.execute("""
        SELECT url, account, password, description, created_at, updated_at
        FROM passwords
        WHERE user_id = ?
        ORDER BY created_at DESC
    """, (current_user['id'],)).fetchall()
    conn.close()
    
    # 生成CSV内容
    output = io.StringIO()
    writer = csv.writer(output)
    
    # 写入标题行
    writer.writerow(['URL', '账号', '密码', '描述', '创建时间', '更新时间'])
    
    # 写入数据行
    for password in passwords:
        writer.writerow([
            password['url'],
            password['account'],
            password['password'],
            password['description'] or '',
            password['created_at'],
            password['updated_at']
        ])
    
    csv_content = output.getvalue()
    output.close()
    
    
    
    # 返回CSV文件
    response = Response(
        content=csv_content.encode('utf-8-sig'),  # 添加BOM以支持Excel正确显示中文
        media_type='text/csv',
        headers={
            'Content-Disposition': f'attachment; filename="passwords_{current_user["username"]}_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv"'
        }
    )
    
    return response